home *** CD-ROM | disk | FTP | other *** search
Text File | 2001-02-02 | 45.5 KB | 1,507 lines |
- ## -*-Tcl-*- (nowrap)
- # ###################################################################
- # AlphaTcl - core Tcl engine
- #
- # FILE: "dialogs.tcl"
- # created: 12/1/96 {5:36:49 pm}
- # last update: 02/02/2001 {17:46:06 PM}
- # Author: Vince Darley
- # E-mail: <vince@santafe.edu>
- # mail: 317 Paseo de Peralta, Santa Fe, NM 87501
- # www: <http://www.santafe.edu/~vince/>
- #
- # Much copyright (c) 1997-2000 Vince Darley, all rights reserved,
- # rest Pete Keleher, Johan Linde.
- #
- # Reorganisation carried out by Vince Darley with much help from Tom
- # Fetherston, Johan Linde and suggestions from the Alpha-D mailing list.
- # Alpha is shareware; please register with the author using the register
- # button in the about box.
- #
- # Description:
- #
- # Much more flexible dialogs for querying the user about flags and
- # vars. These may be global, mode-dependent, or package-dependent.
- #
- # Things you may wish to do:
- #
- # dialog::pkg_options Pkg
- #
- # creates a dialog for all array entries 'PkgmodeVars'. These
- # must have been previously declared using 'newPref'. These
- # variables are _not_ copied into the global scope; only
- # existing as array entries.
- #
- # Note that rather than setting up traces on variables, you are
- # often better off using the optional proc argument to newPref;
- # the name of a procedure to call if that element is changed by
- # the user.
- #
- # Use the procedure 'newPref' to declare preferences. Why? It has
- # optional arguments which allow you to declare:
- #
- # lists
- # indexed lists
- # folders
- # files
- # bindings
- # menu-bindings
- # applications
- # variable-list elements
- # array elements
- #
- # all of which can be set using the same central mode/global
- # dialogs.
- #
- # It also lets you add an optional procedure to call when an
- # item changes... Also if Alpha upgrades to Tcl 8 and namespaces,
- # it is easy to modify that central procedure to fit everything
- # with the new scheme.
- #
- # Most modes will just want to declare their vars using newPref.
- # There is usually no need to do _anything_ else.
- #
- # ---
- #
- # The prefs dialog procs below were based upon Pete Keleher's
- # originals.
- # ###################################################################
- ##
-
- namespace eval dialog {}
- namespace eval global {}
- namespace eval flag {}
-
- # ◊◊◊◊ Toplevel dialog procedures ◊◊◊◊ #
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::pkg_options" --
- #
- # Make a dialog for the given package, with 'title' for the dialog box.
- # 'not_global' indicates the variables are never copied into the global
- # scope, remaining in their array ${pkg}modeVars (or '$var' if it is given)
- #
- # There is now some support for '$var' not to represent an array, but
- # rather to be a namespace inside which the variables are placed.
- # However this hasn't been tested much.
- #
- # Results:
- # Nothing
- #
- # Side effects:
- # May modify any of the given package's variables.
- #
- # --Version--Author------------------Changes-------------------------------
- # 1.0 <vince@santafe.edu> original
- # -------------------------------------------------------------------------
- ##
- proc dialog::pkg_options {pkg {title ""} {not_global 1} {var ""} {listOfVars ""}} {
- if {!$not_global} {
- # make sure the package variables are global
- global ${pkg}modeVars
- if {[info exists ${pkg}modeVars]} {
- foreach v [array names ${pkg}modeVars] {
- global $v
- set $v [set ${pkg}modeVars($v)]
- }
- }
- }
- if {$title == ""} {
- set title "Preferences for the '[quote::Prettify $pkg]' package"
- }
- if {$not_global} {
- global dialog::_not_global_flag
- if {$var == ""} {
- set dialog::_not_global_flag ${pkg}modeVars
- } else {
- set dialog::_not_global_flag $var
- }
- }
- if {[llength $listOfVars]} {
- global dialog::_variablesForEditing
- set dialog::_variablesForEditing $listOfVars
- }
- set err [catch {dialog::modifyModeFlags $title $not_global $pkg} result]
- if {$not_global} {
- global dialog::_not_global_flag
- set dialog::_not_global_flag ""
- }
- if {[info exists dialog::_variablesForEditing]} {
- unset dialog::_variablesForEditing
- }
- if {$err} {
- error $result
- }
- }
- proc dialog::edit_array {var {title ""}} {
- if {$title == ""} {set title "Contents of '$var' array"}
- dialog::pkg_options "" $title 1 $var
- }
- proc dialog::editOneOfMany {title var store tempStore {what ""}} {
- global modifiedArrayElements modifiedVars $tempStore $store
- if {[regexp {(.*)\(.*\)$} $var "" arr elt]} {
- global $arr
- } else {
- global $var
- }
- set oldInfo [array get $tempStore]
- if {[catch {dialog::pkg_options "" $title 1 $tempStore}] \
- || ($oldInfo == [array get $tempStore])} {
- return
- }
- set oldId [set $var]
- if {![dialog::yesno -y "Update" -n "New $what" \
- "Update [set $var] $what, or make a new one?"]} {
- # Ask for new name
- set name [eval prompt [list "Enter tag for new $what" \
- "<Tag>" "Old ids:"] [array names $store]]
- set ${store}($name) [array get $tempStore]
- set $var $name
- # Have to store Usual id too.
- lappend modifiedArrayElements [list $name $store]
- if {[regexp {(.*)\(.*\)$} $var "" arr elt]} {
- lappend modifiedArrayElements [list $elt $arr]
- } else {
- lappend modifiedVars $var
- }
- } else {
- set ${store}($oldId) [array get $tempStore]
- }
- lappend modifiedArrayElements [list $oldId $store]
- }
-
- proc helperApps {} {
- set sigs [info globals *Sig]
- regsub -all {Sig} $sigs {} sigs
- set sig [listpick -p "Change/inspect which helper?" [lsort -ignore $sigs]]
- set sig ${sig}Sig
- global $sig
- if {![info exists $sig]} { set $sig "" }
- set nsig [dialog::askFindApp $sig [set $sig]]
- if {$nsig != "" && [set $sig] != $nsig} {
- set $sig $nsig
- prefs::modified $sig
- }
- }
-
- proc suffixMappings {} {
- global filepats
-
- set dim [getMainDevice]
- set screenwidth [expr {[lindex $dim 2] - [lindex $dim 0]}]
- if {$screenwidth < 800} {
- # Small screen
- if {[catch {listpick -p "Select mode:" [lsort -ignore [array names filepats]]} mode] || $mode == ""} {return}
- set newpats [prompt "Suffix mappings for $mode:" $filepats($mode)]
- if {$newpats != $filepats($mode)} {
- if {![is::List $newpats]} {
- alertnote "'$newpats' is not a valid list of patterns.\
- Please make sure \\\{,\\\} are properly\
- quoted. Your changes have been ignored."
- } else {
- prefs::addArrayElement filepats $mode $newpats
- set filepats($mode) $newpats
- }
- }
- } else {
- set l1 5
- set w1 38
- set l2 [expr {$l1 + $w1 + 5}]
- set w2 [expr {($screenwidth - 200)/2}]
- if {$w2 > 400} { set w2 400 }
- set h 18
- set top 5
- set mar 5
-
- set modes [lsort -ignore [array names filepats]]
- set len [expr {[llength $modes] + 1}]
- set modes1 [lrange $modes 0 [expr {$len/2 - 1}]]
- set modes2 [lrange $modes [expr {$len/2}] end]
-
- foreach m $modes1 {
- lappend items -t $m $l1 $top [expr {$l1 + $w1}] [expr {$top + $h}]
- lappend items -e $filepats($m) $l2 $top [expr {$l2 + $w2}]
- if {[string length $filepats($m)] > 60} {
- lappend items [expr {$top + 2*$h - 2}]
- incr top [expr {2*$h + $mar}]
- } else {
- lappend items [expr {$top + $h - 2}]
- incr top [expr {$h + $mar}]
- }
- }
-
- set top2 5
- set l1 [expr {$l2 + $w2 + 20}]
- set l2 [expr {$l1 + $w1 + 5}]
- foreach m $modes2 {
- lappend items -t $m $l1 $top2 [expr {$l1 + $w1}] [expr {$top2 + $h}]
- lappend items -e $filepats($m) $l2 $top2 [expr {$l2 + $w2}]
- if {[string length $filepats($m)] > 60} {
- lappend items [expr {$top2 + 2*$h - 2}]
- incr top2 [expr {2*$h + $mar}]
- } else {
- lappend items [expr {$top2 + $h - 2}]
- incr top2 [expr {$h + $mar}]
- }
- }
-
- if {$top2 > $top} {
- set top $top2
- }
- incr top $mar
-
- set l1 5
- lappend buts -b OK $l1 $top [expr {$l1 + 60}] [expr {$top + 20}]
- lappend buts -b Cancel [expr {$l1 + 100}] $top [expr {$l1 + 160}] \
- [expr {$top + 20}]
-
- if {[info tclversion] < 8.0} {
- set res [eval [list dialog -w [expr {$l2 + $w2 + 10}] \
- -h [expr {$top + 27}]] $buts $items]
- } else {
- set res [eval [list dialog -w [expr {$l2 + $w2 + 10}] \
- -h [expr {$top + 27}] -T "Suffix mappings"] $buts $items]
- }
-
- if {[lindex $res 0]} {
- set res [lrange $res 2 end]
-
- set changed ""
- foreach m [lsort -ignore [array names filepats]] {
- if {$filepats($m) != [lindex $res 0]} {
- if {[is::List [lindex $res 0]]} {
- lappend changed [list $m [lindex $res 0]]
- } else {
- lappend errors $m
- }
- }
- set res [lrange $res 1 end]
- }
-
- foreach pair $changed {
- eval prefs::addArrayElement filepats [lrange $pair 0 1]
- set filepats([lindex $pair 0]) [lindex $pair 1]
- }
- if {[info exists errors]} {
- alertnote "[join $errors ,]\
- mode[expr {[llength $errors] > 1 ? {s} : {}}] had illegal\
- lists of patterns. Please make sure \\\{,\\\} are properly\
- quoted. Changes to those modes have been ignored."
- }
- }
- }
- mode::updateSuffixes
- }
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::flagsAndVars" --
- #
- # Takes a list of flags and variables (where the latter can in fact
- # contain sublists of stuff), and creates the dialog basing the
- # title for each item on its name, extracting help text as required,
- # and basing the type of each item on either its name or the type
- # which has been registered.
- #
- # The procedure used to be named 'dialog::mode', but has been
- # renamed to reflect it's broader purpose. It will return two lists,
- # the first of the values returned, the second of the variables which
- # should be set to those values. The calling procedure should ensure
- # that the variables are actually set to these values!
- #
- # The current values for the flags/vars must be accessible, since
- # they will be required by the code this procedure calls. By default
- # it is assumed each flag/var is a global variable, unless various
- # other information is declared in various globals. The method
- # which is actually called to get the values is dialog::getFlag,
- # which usually calls dialog::getOldFlag.
- #
- # Please see those methods for details if you want to call this
- # procedure without using global variables.
- # -------------------------------------------------------------------------
- ##
- proc dialog::flagsAndVars {flags vars {title ""}} {
- set lim [expr {10 - [llength $flags]/4}]
- if {[llength $vars] > $lim } {
- set args {}
- set nvars [llength $vars]
- set j 0
- for {set i 0} {$i < $nvars} {incr i $lim ; set lim 10} {
- lappend args [list "Page [incr j] of ${title}" $flags \
- [lrange $vars $i [expr {$i+$lim -1}]]]
- set flags ""
- }
- dialog::multipage $title $args
- } else {
- dialog::onepage $flags $vars $title
- }
- }
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::modifyModeFlags" --
- #
- # Currently 'not_global == 0' implies this is a mode, or at least that
- # the variables are stored in ${mm}modeVars(...)
- #
- # 'not_global == 1' implies that the variables are stored in the
- # array/namespace given by the value of the variable
- # 'dialog::_not_global_flag'
- #
- # -------------------------------------------------------------------------
- ##
- proc dialog::modifyModeFlags {{title ""} {not_global 0} {mm ""}} {
- global mode invisibleModeVars \
- dialog::_not_global_flag allFlags
- # Check whether this is a mode or package, and where variable values
- # are stored, and whether that's at the global level as well as in
- # an array...
- if {$not_global} {
- set storage ${dialog::_not_global_flag}
- if {$title == ""} {
- set title "Preferences for '${mm}' package"
- }
- } else {
- if {$mm == ""} {
- set mm $mode
- if {$mm == ""} {
- alertnote "No mode set!"
- return
- }
- }
- set storage ${mm}modeVars
- if {$title == ""} {
- set title "Preferences for '${mm}' mode"
- }
- }
- # check for mode specific proc
- if {[info commands ${mm}modifyFlags] != ""} {${mm}modifyFlags; return}
- if {[info tclversion] >= 8.0} { set storage ::$storage }
- set unsortedNames {}
- global $storage ${storage}Invisible index::flags index::feature\
- dialog::_variablesForEditing
- if {[info exists dialog::_variablesForEditing]} {
- set unsortedNames ${dialog::_variablesForEditing}
- } elseif {[array exists $storage]} {
- set unsortedNames [array names $storage]
- } elseif {[namespace_exists $storage]} {
- foreach var [info vars ${storage}::*] {
- # Caution: Tcl 8 or newer only.
- lappend unsortedNames [namespace tail $var]
- }
- }
- if {[llength $unsortedNames]} {
- set mflags {}
- set mvars {}
- set colors {}
- set rest {}
- foreach i $unsortedNames {
- if {[regexp {Colou?r$} $i]} {
- lappend colors $i
- } else {
- lappend rest $i
- }
- }
-
- foreach v [concat [lsort $rest] [lsort $colors]] {
- if {[info exists invisibleModeVars($v)] \
- || [info exists ${storage}Invisible($v)]} continue
-
- if {[lsearch -exact $allFlags $v] >= 0} {
- lappend mflags $v
- } else {
- lappend mvars $v
- }
- }
- foreach pkg [set index::flags] {
- if {[lsearch -exact [lindex [set index::feature($pkg)] 1] $mm] != -1} {
- lappend mflags $pkg
- }
- }
- if {![llength $mflags] && ![llength $mvars]} {
- alertnote "There are no preferences!"
- return
- }
- if {[catch {dialog::flagsAndVars $mflags $mvars $title} values_items]} {
- return
- }
- dialog::adjust_flags \
- [expr {$not_global ? "arraynamespace" : "arrayglobal"}] \
- $values_items $storage
- } else {
- alertnote "The '$mm' mode/package has no preference settings."
- }
-
- hook::callAll dialog::modifyModeFlags $mm $title
-
- }
-
- proc global::allPrefs {{which "AllPreferences"}} {
- dialog::resetModified
- global flagPrefs varPrefs
- global::updateHelperFlags
- global::updatePackageFlags
- set AllPreferences [array names flagPrefs]
- set InterfacePreferences {Appearance Completions Electrics Text Tiling Window}
- set Input-OutputPreferences {Backups Files Printer Tags WWW}
- set SystemPreferences [lremove -l $AllPreferences \
- $InterfacePreferences ${Input-OutputPreferences} Packages]
- foreach nm [set [join ${which} ""]] {
- lappend args [list $nm $flagPrefs($nm) $varPrefs($nm)]
- }
- dialog::is_global {
- dialog::adjust_flags global [dialog::multipage $which $args]
- }
- }
-
- proc dialog::preferences {menu nm} {
- global flagPrefs varPrefs
- if {[string match "Suffix Mappings" $nm]} {
- return [suffixMappings]
- } elseif {[string match "Menus And Features" $nm]} {
- return [global::menusAndFeatures]
- } elseif {[string match "Menus" $nm]} {
- return [global::menus]
- } elseif {[string match "Features" $nm]} {
- return [global::features]
- } elseif {[string match "Save Preferences Now" $nm]} {
- return [prefs::saveNow]
- } elseif {[string match "Edit Prefs File" $nm]} {
- return [prefs::tclEdit]
- }
- if {![info exists flagPrefs($nm)]} {
- set nm "[string toupper [string index $nm 0]][string range $nm 1 end]"
- }
- if {[string match "*Preferences" $nm]} { return [global::allPrefs $nm] }
- if {$nm == "Packages"} { global::updatePackageFlags }
- if {$nm == "Helper Applications"} { global::updateHelperFlags }
- dialog::is_global {
- dialog::adjust_flags global [dialog::onepage $flagPrefs($nm) $varPrefs($nm) "$nm preferences…"]
- }
- }
-
- # Dominique's nice proc to handle all packages at once.
- proc global::allPackages {} {
- global package::prefs allFlags dialog::_not_global_pkg dialog::_not_global_flag
- global flagPrefs varPrefs alpha::prefs
- global::updatePackageFlags
- set args {}
- set dialog::_not_global_pkg {}
- if {[info exists package::prefs]} {
- set pkglist [concat ${package::prefs} [list miscellaneousPackages]]
- } else {
- set pkglist [list miscellaneousPackages]
- }
- foreach pkg [lsort -ignore $pkglist] {
- if {$pkg == "miscellaneousPackages"} {
- lappend args [list miscellaneousPackages $flagPrefs(Packages) $varPrefs(Packages)]
- continue
- }
- if {[info exists alpha::prefs($pkg)]} {
- set pkg [set alpha::prefs($pkg)]
- }
- global ${pkg}modeVars
- set mflags {}
- set mvars {}
- if {[array exists ${pkg}modeVars]} {
- lappend dialog::_not_global_pkg ${pkg}modeVars
- foreach v [lsort [array names ${pkg}modeVars]] {
- if {[lsearch -exact $allFlags $v] >= 0} {
- lappend mflags $v
- } else {
- lappend mvars $v
- }
- }
- }
- lappend args [list $pkg $mflags $mvars]
- }
-
- set values_items [dialog::multipage "Packages preferences" $args]
- #set values_items [dialog::multipage [concat "package" ${package::prefs}] $args]
- set dialog::_not_global_flag {}
- set res [lindex $values_items 0]
- set editItems [lindex $values_items 1]
- set i 0
- set values {}
- set items {}
- foreach item $editItems {
- global $item
- if {[info exists $item]} {
- lappend values [lindex $res $i]
- lappend items $item
- }
- incr i
- }
- dialog::adjust_flags global [list $values $items]
- foreach pkg ${dialog::_not_global_pkg} {
- set i 0
- set values {}
- set items {}
- foreach item $editItems {
- if {[info exists ${pkg}($item)]} {
- lappend values [lindex $res $i]
- lappend items $item
- }
- incr i
- }
- set dialog::_not_global_flag $pkg
- dialog::adjust_flags arraynamespace [list $values $items] $pkg
- }
- unset dialog::_not_global_pkg
- set dialog::_not_global_flag {}
- }
-
- # ◊◊◊◊ Simple queries and alerts ◊◊◊◊ #
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::value_for_variable" --
- #
- # Ask for a value, with default given by the given variable, and using
- # that variable's type (list, file, ...) as a constraint.
- #
- # Currently assumes the variable is a list var, but this will change.
- # -------------------------------------------------------------------------
- ##
- proc dialog::value_for_variable {var {title ""}} {
- if {$title == ""} { set title [quote::Prettify $var] }
- return [dialog::optionMenu $title [flag::options $var] \
- [uplevel [list set $var]]]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::getAKey" --
- #
- # Returns a keystring to be used for binding a key in a menu,
- # using a nice dialog box to ask the user.
- #
- # Possible improvements: we could replace the dialog
- # box with a status-line prompt (which would allow the use of
- # getModifiers to check what keys the user pressed).
- #
- # Now handles 'prefixChar' bindings for non-menu items.
- # i.e. you can use this dialog to bind something to 'ctrl-x ctrl-s',
- # for instance.
- #
- # If the name contains '/' it is considered to be two items,
- # separated by that '/', which are to take the same binding,
- # except that one of them will use the option key.
- #
- # Similarly '//' means use shift, '///' means shift-option,
- # For instance 'dialog::getAKey close/closeAll//closeFloat /W<O'
- # would give you the menu-item for 'close' in the file menu.
- # except these last two aren't implemented yet ;-)
- # --Version--Author------------------Changes-------------------------------
- # 1.0 Johan Linde original
- # 1.1 <vince@santafe.edu> can do non-menu bindings too
- # 1.2 <vince@santafe.edu> handles arrow keys
- # 1.2.1 Johan Linde handles key pad keys
- # -------------------------------------------------------------------------
- ##
- proc dialog::getAKey {{name {}} {keystr {}} {for_menu 1}} {
- global keys::func
- # two lists for any other keys which look better with a text description
- set otherKeys {"<No binding>" "-" Space}
- set otherKeyChars [list "" "" " "]
- if {!$for_menu} {
- lappend otherKeys Left Right Up Down "Key pad =" \
- "Key pad /" "Key pad *" "Key pad -" "Key pad +" "Key pad ."
- lappend otherKeyChars "" "" "\x10" "" Kpad= \
- Kpad/ Kpad* Kpad- Kpad+ Kpad.
- for {set i 0} {$i < 10} {incr i} {
- lappend otherKeys "Key pad $i"
- lappend otherKeyChars Kpad$i
- }
- }
- set nname $name
- set shift-opt [expr {![regsub {///} $nname { so-} $nname]}]
- set shift [expr {![regsub {//} $nname { s-} $nname]}]
- set option [expr {![regsub {/} $nname { o-} $nname]}]
- if {[string length $keystr]} {
- set values "0 0"
- set mkey [keys::verboseKey $keystr normal]
- if {$normal} {
- lappend values "Normal Key"
- } else {
- lappend values $mkey
- set mkey {}
- }
- lappend values [regexp {<U} $keystr]
- lappend values [regexp {<B} $keystr]
- if {!$for_menu} {
- if {[regexp "«(.*)»" $keystr "" i]} {
- if {$i == "e"} {
- lappend values "escape"
- } else {
- lappend values "ctrl-$i"
- }
- } else {
- lappend values "<none>"
- }
- }
- if {$option} {lappend values [regexp {<I} $keystr]}
- lappend values [regexp {<O} $keystr]
- lappend values $mkey
- } else {
- set values {0 0 "" 0 0}
- if {!$for_menu} { lappend values <none> }
- if {$option} {lappend values 0}
- lappend values 0 ""
- }
- if {$for_menu} {
- set title "Menu key binding"
- } else {
- set title "Key binding"
- set prefixes [keys::findPrefixChars]
- foreach i $prefixes {
- lappend prefix "ctrl-$i"
- }
- lappend prefixes e
- lappend prefix "escape"
- }
- if {$name != ""} { append title " for '$name'" }
- set usep [info exists prefix]
- global alpha::modifier_keys
- while {1} {
- set box ""
- # Build box
- if {[info tclversion] < 8.0} {
- lappend box -t $title 10 10 315 25
- } else {
- lappend box -T $title
- }
- lappend box -t Key 10 40 40 55 \
- -m [concat [list [lindex $values 2]] \
- [list "Normal key"] $otherKeys ${keys::func}] 80 40 180 57 \
- -c Shift [lindex $values 3] 10 70 60 85 \
- -c Control [lindex $values 4] 80 70 150 85
- if {$usep} {
- lappend box -t Prefix 190 40 230 55 \
- -m [concat [list [lindex $values 5]] "<none>" "-" $prefix] \
- 235 40 315 57
- }
- if {$option} {
- lappend box -c [lindex ${alpha::modifier_keys} 2] \
- [lindex $values [expr {5 + $usep}]] 160 70 220 85
- }
- lappend box -c [lindex ${alpha::modifier_keys} 0] \
- [lindex $values [expr {5 + $option +$usep}]] 230 70 315 85
- lappend box -n "Normal key" -e [lindex $values [expr {6 + $option +$usep}]] 50 40 70 55
- set values [eval [concat dialog -w 330 -h 130 -b OK 20 100 85 120 -b Cancel 105 100 170 120 $box]]
- # Interpret result
- if {[lindex $values 1]} {error "Cancel"}
- # work around a little Tcl problem
- regsub "\{\{\}" $values "\\\{" values
- set elemKey [string toupper [string trim [lindex $values [expr {6 + $option +$usep}]]]]
- set special [lindex $values 2]
- set keyStr ""
- if {[lindex $values 3]} {append keyStr "<U"}
- if {[lindex $values 4]} {append keyStr "<B"}
- if {$option && [lindex $values [expr {5 + $usep}]]} {append keyStr "<I"}
- if {[lindex $values [expr {5 + $option +$usep}]]} {append keyStr "<O"}
- if {$usep} {
- set pref [lindex $values 5]
- if {$pref != "<none>"} {
- set i [lsearch -exact $prefix $pref]
- append keyStr "«[lindex $prefixes $i]»"
- }
- }
- if {[string length $elemKey] > 1 && $special == "Normal key"} {
- alertnote "You should only give one character for key binding."
- } else {
- if {$for_menu} {
- if {$special == "Normal key" && [text::Ascii $elemKey] > 126} {
- alertnote "Sorry, can't define a key binding with $elemKey."
- } elseif {$elemKey != "" && $special == "Normal key" && ($keyStr == "" || $keyStr == "<U")} {
- alertnote "You must choose at least one of the modifiers control, option and command."
- } elseif {![regexp {F[0-9]} $special] && $special != "Tab" && $special != "Normal key" && $special != "<No binding>" && $keyStr == ""} {
- alertnote "You must choose at least one modifier."
- } else {
- break
- }
- } else {
- break
- }
- }
- }
- if {$special == "<No binding>"} {set elemKey ""}
- if {$special != "Normal key" && $special != "<No binding>"} {
- if {[set i [lsearch -exact $otherKeys $special]] != -1} {
- set elemKey [lindex $otherKeyChars $i]
- } else {
- set elemKey [text::Ascii [expr {[lsearch -exact ${keys::func} $special] + 97}] 1]
- }
- }
- if {![string length $elemKey]} {
- set keyStr ""
- } else {
- append keyStr "/$elemKey"
- }
- return $keyStr
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::optionMenu" --
- #
- # names is the list of items. An item '-' is a divider, and empty items
- # are not allowed.
- # -------------------------------------------------------------------------
- ##
- proc dialog::optionMenu {prompt names {default ""} {index 0}} {
- if {$default == ""} {set default [lindex $names 0]}
-
- set y 5
- set w [expr {[string length $prompt] > 20 ? 350 : 200}]
- if {[string length $prompt] > 60} { set w 500 }
-
- # in case we need a wide pop-up area that needs more room
- set popUpWidth [eval dialog::_reqWidth $names]
- set altWidth [expr {$popUpWidth + 60}]
- set w [expr {$altWidth > $w ? $altWidth : $w}]
-
- set dialog [dialog::text $prompt 5 y [expr {int($w/6.7)}]]
- incr y 10
- eval lappend dialog [dialog::menu 30 y $names $default $popUpWidth]
- incr y 20
- eval lappend dialog [dialog::okcancel [expr {$w - 160}] y 0]
- set res [eval dialog -w $w -h $y $dialog]
-
- if {[lindex $res 2]} { error "Cancel" }
- # cancel was pressed
- if {$index} {
- # we have to take out the entries correponding to pop-up
- # menu separator lines -trf
- set possibilities [lremove -all $names "-"]
- return [lsearch -exact $possibilities [lindex $res 0]]
- } else {
- return [lindex $res 0]
- }
- }
-
- proc dialog::getUrl {{prompt "Please type your url, or use one of the buttons below"} {url ""}} {
- while {1} {
- set y 5
- set w 380
- if {[info tclversion] >= 8.0} {
- set dialog [list -T "Select URL"]
- } else {
- set dialog [list]
- }
-
- eval lappend dialog [dialog::text $prompt 5 y [expr {int($w/6.7)}]]
- incr y 10
- eval lappend dialog [dialog::edit $url 10 y 35]
- incr y 5
- eval lappend dialog [dialog::button "Pick local file…" 10 y \
- "Use foremost browser page" 150 y]
- eval lappend dialog [dialog::okcancel [expr {$w - 160}] y 0]
- set res [eval dialog -w $w -h $y $dialog]
-
- if {[lindex $res 1]} {
- # pick local file
- if {[string range $url 0 6] == "file://"} {
- set default [string range $url 7 end]
- } else {
- set default ""
- }
- if {![catch {getfile "Pick local file to use as url" $default} file]} {
- regsub -all { } $file {%20} file
- set url "file:///$file"
- }
- } elseif {[lindex $res 2]} {
- # use browser page
- if {[catch {url::browserWindow} res]} {
- alertnote "Can't get that information: $res"
- } else {
- set url $res
- }
- } elseif {[lindex $res 3]} {
- # ok
- return [lindex $res 0]
- } elseif {[lindex $res 4]} {
- # cancel
- error "Cancel"
- }
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::alert" --
- #
- # Identical to 'alertnote' but copes with larger blocks of text, and
- # resizes to that text as appropriate.
- # -------------------------------------------------------------------------
- ##
- proc dialog::alert {args} {
- eval [list dialog::yesno -y "Ok" -n ""] $args
- }
-
- proc dialog::errorAlert {args} {
- eval dialog::alert $args
- error [lindex $args 0]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::yesno" --
- #
- # Make a dialog with between 1 and 3 buttons, representing '1', '0' and
- # error "Cancel" respectively. The names of the first two can be given
- # with '-y name' and '-n name' respectively. The cancel button is
- # only used if a '-c' flag is given (and its name is fixed).
- #
- # The procedure automatically sizes the dialog and buttons to fit the
- # enclosed text.
- # -------------------------------------------------------------------------
- ##
- proc dialog::yesno {args} {
- # too long for Alpha's standard dialog
- getOpts {-y -n}
- set prompt [lindex $args 0]
- set y 5
- set w [expr {[string length $prompt] > 20 ? 350 : 200}]
- if {[string length $prompt] > 60} { set w 500 }
-
- set dialog [dialog::text $prompt 5 y [expr {int($w/6.7)}]]
- incr y 10
- set x 10
- if {[info exists opts(-y)] && $opts(-y) != ""} {
- lappend buttons $opts(-y) "" y
- } else {
- lappend buttons "Yes" "" y
- }
- if {[info exists opts(-n)]} {
- if {$opts(-n) != ""} {
- lappend buttons $opts(-n) "" y
- }
- } else {
- lappend buttons "No" "" y
- }
- if {[info exists opts(-c)]} {
- lappend buttons "Cancel" "" y
- }
- eval lappend dialog [eval dialog::button $buttons]
- if {$x > $w} { set w [expr {$x + 15}] }
- set res [eval dialog -w $w -h $y $dialog]
- if {[lindex $res 0]} {
- return 1
- } elseif {[lindex $res 1]} {
- return 0
- } else {
- error "cancelled"
- }
- }
-
- proc dialog::password {{msg "Please enter password:"}} {
- set values [dialog -w 300 -h 90 -t $msg 10 20 290 35 \
- -e "" 10 40 290 42 -b OK 20 60 85 80 -b Cancel 105 60 170 80]
- if {[lindex $values 2]} {error "Cancel"}
- return [lindex $values 0]
- }
-
- proc dialog::logon {pkg {msg "Log on as…"} {connect "Connect"} {cancel "Cancel"} {var ""}} {
- set y 20
-
- global dialog::_not_global_flag
- if {$var == ""} {
- set dialog::_not_global_flag ${pkg}modeVars
- } else {
- set dialog::_not_global_flag $var
- }
-
- if {$msg != ""} {
- set dialog [dialog::title $msg 480]
- incr y 25
- }
-
- eval lappend dialog [dialog::buildSection {userName userPassword} y]
- incr y 10
- set x 300
- eval lappend dialog [dialog::button $connect "" y $cancel "" y ]
- set res [eval dialog -w 480 -h $y $dialog]
-
- dialog::modified userName [lindex $res 0]
- dialog::modified userPassword [lindex $res 1]
-
- # 1 if "connect", 0 if "cancel"
- return [lindex $res 2]
- }
-
- # ◊◊◊◊ Finding applications ◊◊◊◊ #
-
-
- proc dialog::askFindApp {var sig} {
- if {$sig == ""} {
- set text "Currently unassigned. Set?"
- } elseif {[catch {nameFromAppl '$sig'} name]} {
- set text "App w/ sig '$sig' doesn't seem to exist. Change?"
- } else {
- set text "Current value is '$name'. Change?"
- }
- if {[dialog::yesno $text]} {
- set nsig [dialog::findApp $var $sig]
- set app [nameFromAppl $nsig]
- if {[dialog::yesno "Are you sure you want to set $var to '$nsig'\
- (mapped to '$app')?"]} {
- return $nsig
- }
- }
- return ""
- }
-
- # The optional second argument can be used to prompt the user
- # with the 'old' value
- proc dialog::findApp {var {sig ""}} {
- global ${var}s modifiedVars
- if {[info exists ${var}s]} {
- # have a list of items
- set sigs [set ${var}s]
-
- set s 0
- foreach f $sigs {
- if {![catch {nameFromAppl $f} path]} {
- lappend items [file tail $path]
- lappend itemsigs $f
- incr s
- }
- }
- if {$s} {
- lappend items "-" "Locate manually…"
- if {[catch {dialog::optionMenu "Select a new helper for '$var':" \
- $items "" 1} p]} {
- return ""
- }
- # we removed a bunch of items above, so have to look here
- if {$p < $s} {
- return [lindex $itemsigs $p]
- }
- }
- if {!$s || $p >= $s} {
- set nsig [dialog::_findApp $var $sig]
- if {$nsig != ""} {
- if {[lsearch $sigs $nsig] == -1} {
- lappend ${var}s $nsig
- lappend modifiedVars ${var}s
- }
- }
- } else {
- set nsig [lindex $sigs $p]
- }
- return $nsig
- } else {
- return [dialog::_findApp $var $sig]
- }
- }
-
- proc dialog::findAnyApp {{prompt "Locate application:"}} {
- if {[catch {getfile $prompt} path]} {return ""}
- return $path
- }
-
- proc dialog::_findApp {var {sig ""}} {
- global alpha::platform
- if {${alpha::platform} == "alpha"} {
- set dir ""
- } else {
- set dir [file dirname $sig]
- }
- if {[catch {getfile "Locate new helper for '$var':" $sig} path]} { return "" }
- set nsig [getFileSig $path]
- set app [nameFromAppl $nsig]
- if {$app != $path} {
- alertnote "Appl sig '$nsig' is mapped to '$app', not '$path'. Remove the former, or rebuild your desktop."
- return ""
- }
- return $nsig
- }
-
- # ◊◊◊◊ Global/mode menus ◊◊◊◊ #
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::pickMenusAndFeatures" --
- #
- # Prompt the user to select menus and features either globally or
- # for a given mode. We need to make sure that those items in
- # the mode-list which are also in the global list aren't forgotten
- # (since they are removed from the dialog).
- #
- # 'mfb' is 0 for both menus and features
- # 1 for just menus
- # 2 for just features
- #
- # This procedure should be pretty clear now, having been rewritten.
- # However, here are a few tips:
- #
- # Each page of the dialog may contain 2 or 3 sections. The items
- # to use in these sections are taken from the variables:
- #
- # menus1, menus2, menus3
- # features1, features2, features3
- # off1, off2
- #
- # Where if the variable is empty, the entire section is omitted.
- # Furthermore, all 'always on' items are ignored, and for mode
- # dialogs, anything which is globally on is moved from the menus
- # or features pages to the 'off' pages.
- # -------------------------------------------------------------------------
- ##
- proc dialog::pickMenusAndFeatures {formode {mfb 0}} {
- global mode::features global::features alpha::packagesAlwaysOn \
- index::flags index::feature
- set all [package::partition $formode]
- set menus1 [lindex $all 0]
- set menus2 [lindex $all 1]
- set menus3 [lindex $all 2]
- set features1 [lindex $all 3]
- set features2 [lindex $all 4]
- set features3 [lindex $all 5]
- unset all
-
- if {[info tclversion] >= 8.0} {
- set help {}
- }
- # decide on two or three column
- #set endw [expr [llength $all] > 50 ? 560 : 380]
- set endw 560
-
- if {$formode == "global"} {
- set chosen ${global::features}
- set prefix "Select global #"
- set maintypes [list Usual "" "Other possible"]
- } else {
- set chosen {}
- set extras_off {}
- set off1 {}
- set off2 {}
- foreach pkg [mode::getFeatures $formode] {
- if {[string index $pkg 0] == "-"} {
- set pkg [string range $pkg 1 end]
- if {[lsearch -exact ${global::features} $pkg] != -1} {
- # these are the ones which are disabled
- lappend extras_off $pkg
- }
- } else {
- # These are items which are on for this mode. Any of these
- # which are also on globally go in the first group of 'off'
- # items. The rest in the first pages.
- lappend chosen $pkg
- }
- }
- foreach pkg [set global::features] {
- if {[lsearch -exact $chosen $pkg] != -1} {
- # The top group of items
- if {[lindex [set index::feature($pkg)] 2] == 1} {
- # it's a menu
- if {$mfb != 2} {lappend off1 $pkg}
- } else {
- # it's not a menu
- if {$mfb != 1} {lappend off1 $pkg}
- }
- } else {
- # The second group of items
- if {[lindex [set index::feature($pkg)] 2] == 1} {
- # it's a menu
- if {$mfb != 2} {lappend off2 $pkg}
- } else {
- # it's not a menu
- if {$mfb != 1} {lappend off2 $pkg}
- }
- }
- }
-
- set prefix "Select # for mode '$formode'"
- set maintypes [list Usual General "Other possible"]
- set multipage 1
- }
- while 1 {
- set maxh 0
- set box ""
- #set names {}
- foreach type {menus features off} {
- if {$formode == "global" && $type == "off"} {continue}
- if {$mfb > 0} {
- if {$mfb == 1 && $type == "features"} {continue}
- if {$mfb == 2 && $type == "menus"} {continue}
- }
- set w 20
- set h 45
- set i 0
- if {$type == "off"} {
- set subm "Turn items off"
- set types [list "Usually on for this mode" "Uncheck to disable"]
- } else {
- regsub "\#" $prefix $type subm
- set types $maintypes
- }
- set page 1
- if {![info exists names0]} {
- lappend names0 $subm
- lappend names $subm
- }
- lappend names $subm
- lappend box "-n" $subm
- if {$type == "off"} {
- lappend box -t "These items are currently globally on. You can turn them off just for this mode here." 10 $h [expr {$endw -20}] [expr {$h +15}]
- incr h 20
- }
- foreach block $types {
- incr i
- if {[llength [set ${type}$i]] == 0} {
- continue
- }
- if {($type == "off")} {
- lappend box -t "$block:"
- } else {
- lappend box -t "$block $type:"
- }
- lappend box 10 $h [expr {$w +160}] [expr {$h +15}]
- incr h 20
- foreach m [set ${type}$i] {
- if {[lsearch -exact [set alpha::packagesAlwaysOn] $m] != -1} {
- continue
- }
- if {$h > 360} {
- if {$h > $maxh} {set maxh $h}
- incr page
- lappend names "$subm page $page"
- lappend box "-n" "$subm page $page"
- set h 45
- lappend box -t "$block $type continued..." 10 $h \
- [expr {$w +260}] [expr {$h +15}]
- incr h 20
- }
- set name [quote::Prettify $m]
- if {[info exists tmpcurrent]} {
- # Second or more times through we just recreate what we
- # have so far
- set tick [lindex $tmpcurrent $ii]
- incr ii
- } else {
- # First time through, we need to work out whether each item
- # is on or off, and rememeber all the items.
- if {$type == "off"} {
- set tick [expr {([lsearch -exact $extras_off $m] < 0)}]
- lappend orig [list "off" $m $tick]
- } else {
- set tick [expr {([lsearch -exact $chosen $m] >= 0)}]
- lappend orig [list "on" $m $tick]
- }
- }
- lappend box -c $name $tick $w $h [expr {$w + 160}] [expr {$h + 15}]
- if {[info tclversion] >= 8.0} {
- lappend help [dialog::packagehelp $m 1]
- }
- incr w 180
- if {$w == $endw} {set w 20; incr h 20}
- }
- if {$w != 20} {
- incr h 30 ; set w 20
- }
- }
- if {$h > $maxh} {set maxh $h}
-
- }
- set h $maxh
- incr h 20
-
- if {[llength $names] == 2} {
- set offset 4
- set name_piece [list -t [lindex $names 0]]
- if {[set nindex [lsearch -exact $box -n]] != -1} {
- set box [lreplace $box $nindex [incr nindex]]
- }
- set singlepage 1
- } else {
- set offset 5
- set name_piece [list -m $names]
- set singlepage 0
- }
-
- if {[info tclversion] >= 8.0} {
- if {$formode == "global"} {
- set title "Global"
- } else {
- set title "$formode"
- }
- switch -- $mfb {
- 0 { append title " menus and features" }
- 1 { append title " menus" }
- 2 { append title " features" }
- }
- lappend box -T $title
- set values [eval [concat dialog -w $endw -h [expr {$h + 30}] \
- -b OK 20 $h 85 [expr {$h + 20}] \
- -b Cancel 105 $h 170 [expr {$h + 20}] \
- -b Help [expr {$endw -200}] $h [expr {$endw - 140}] [expr {$h + 20}] \
- -b Descriptions [expr {$endw -120}] $h [expr {$endw -20}] [expr {$h + 20}] \
- $name_piece [expr {($endw - 220)/2}] 10 $endw 30 $box\
- -help] [list [concat [list \
- "Click here to save the current settings." \
- "Click here to discard any changes you've made to the settings." \
- "Click here to access help on each item in this dialog." \
- "Click here to access descriptions of each item in this dialog."] \
- [expr {$singlepage ? "" : {"Use this popup menu, or the cursor keys to select a \
- different page of preferences."}}] \
- $help]]]
- } else {
- set values [eval [concat dialog -w $endw -h [expr {$h + 30}] \
- -b OK 20 $h 85 [expr {$h + 20}] \
- -b Cancel 105 $h 170 [expr {$h + 20}] \
- -b Help [expr {$endw -200}] $h [expr {$endw - 140}] [expr {$h + 20}] \
- -b Descriptions [expr {$endw -120}] $h [expr {$endw -20}] [expr {$h + 20}] \
- $name_piece [expr {($endw - 220)/2}] 10 $endw 30 $box]]
- }
-
- if {[llength $names] > 2} {
- set names0 [list [lindex $values 4]]
- }
- set names $names0
- if {[lindex $values 0]} {
- set tmpcurrent [lrange $values $offset end]
- # Ok
- break
- }
- if {[lindex $values 1]} {
- # Cancel
- return
- }
- if {[lindex $values 2]} {
- dialog::describeMenusAndFeatures Help
- }
- if {[lindex $values 3]} {
- dialog::describeMenusAndFeatures Describe
- }
- set tmpcurrent [lrange $values $offset end]
- set ii 0
- #unset names0
- }
- set res_on {}
- set res_off {}
-
- global mode
-
- for {set i 0} {$i < [llength $tmpcurrent]} {incr i} {
- set choice [lindex $tmpcurrent $i]
- set original [lindex $orig $i]
- set onoff [lindex $original 0]
- set m [lindex $original 1]
- set tick [lindex $original 2]
- if {$onoff == "on"} {
- # From the 'on' section of the dialog
- if {$choice && !$tick} {
- lappend res_on $m
- if {$formode == "global"} {
- lappend global::features $m
- } else {
- lappend mode::features($formode) $m
- prefs::modified mode::features($formode)
- }
- } elseif {!$choice && $tick} {
- lappend res_off $m
- if {$formode == "global"} {
- set global::features [lremove [set global::features] $m]
- } else {
- set mode::features($formode) [lremove [set mode::features($formode)] $m]
- prefs::modified mode::features($formode)
- }
- }
- } else {
- # From the 'off' section of the dialog
- if {$formode == "global"} {error "Shouldn't be here"}
- if {$choice && !$tick} {
- lappend res_on $m
- # It is on globally, and we previously turned it off for this mode
- set mode::features($formode) [lremove [set mode::features($formode)] "-$m"]
- } elseif {!$choice && $tick} {
- lappend res_off $m
- # It is on globally, and we now turn it off for this mode
- lappend mode::features($formode) "-$m"
- prefs::modified mode::features($formode)
- }
- }
- }
- # Finally carry out the (de)activation
- foreach m $res_off {
- package::deactivate $m
- }
- foreach m $res_on {
- package::activate $m
- }
- }
-
- proc dialog::describeMenusAndFeatures {{what "Help"}} {
- set all [package::partition]
- set okmenu [lindex $all 0]
- set okfeature [lindex $all 1]
- set okmode [lindex $all 2]
- set all [eval concat $all]
- # decide on two or three column
- set endw [expr {[llength $all] > 50 ? 560 : 380}]
- if {$what == "Help"} {
- set prefix "Read help for a #"
- } else {
- set prefix "Describe a #"
- }
- foreach m {menu feature mode} {
- regsub "\#" $prefix $m subm
- lappend names $subm
- }
- lappend box -m [concat [list [lindex $names 0]] $names] \
- [expr {($endw - 150)/2}] 10 $endw 30
- set maxh 0
- set wincr 160
- foreach type {menu feature mode} {
- set w 20
- set h 45
- regsub "\#" $prefix $type subm
- lappend box "-n" $subm
- if {$type == "mode"} {set wincr 70}
- foreach m [set ok$type] {
- set name [quote::Prettify $m]
- lappend box -b $name $w $h [expr {$w + $wincr}] [expr {$h + 15}]
- incr w [expr {$wincr +20}]
- if {$w == $endw} {set w 20; incr h 20}
- }
- if {$w > 20} {set w 20; incr h 20}
- if {$h > $maxh} {set maxh $h}
- }
- set h $maxh
- incr h 20
- while 1 {
- set values [eval [concat [list dialog -w $endw -h [expr {$h + 30}] \
- -b OK 20 $h 85 [expr {$h + 20}]] $box]]
- if {[lindex $values 0]} {return}
- # we hit a button
- for {set i 0} {$i < [llength $all]} {incr i} {
- if {[lindex $values [expr {$i + 2}]]} {
- if {$what == "Help"} {
- package::helpFile [lindex $all $i]
- } else {
- package::describe [lindex $all $i]
- }
- break
- }
- }
- }
- }
-
-
- # ◊◊◊◊ Multiple bindings dialogs ◊◊◊◊ #
-
- proc dialog::arrayBindings {name array {for_menu 0}} {
- upvar $array a
- foreach n [array names a] {
- lappend l [list $a($n) $n]
- }
- if {[info exists l]} {
- eval dialog::adjustBindings [list $name modified "" $for_menu] $l
- }
- array set a [array get modified]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::adjustBindings" --
- #
- # 'args' is a list of pairs. The first element of each pair is the
- # menu binding, and the second element is a descriptive name for the
- # element. 'array' is the name of an array in the calling proc's
- # scope which is used to return modified bindings.
- #
- # Results:
- #
- # --Version--Author------------------Changes-------------------------------
- # 1.0 Johan Linde original for html mode
- # 1.1 <vince@santafe.edu> general purpose version
- # 1.2 Johan Linde split into two pages when many items
- # -------------------------------------------------------------------------
- ##
- proc dialog::adjustBindings {name array {mod {}} {for_menu 1} args} {
- global screenHeight
- regsub -all {\"\(-\"} $args "" items
- upvar $array key_changes
-
- foreach it $items {
- if {[info exists key_changes([lindex $it 1])]} {
- set tmpKeys([lindex $it 1]) $key_changes([lindex $it 1])
- } else {
- set tmpKeys([lindex $it 1]) [lindex $it 0]
- }
- }
- # do we return modified stuff?
- if {$mod != ""} { upvar $mod modified }
- set modified ""
- set page "Page 1 of $name"
- while {1} {
- # Build dialog.
- set twoWindows 0
- set box ""
- set h 30
- foreach it $items {
- if {$it == "(-"} {continue}
- set w 210
- set w2 370
- set key $tmpKeys([lindex $it 1])
- set key1 [dialog::specialView::binding $key]
- set it2 [split [lindex $it 1] /]
- if {[llength $it2] == 1} {
- lappend box -t [lindex $it2 0] 65 $h 205 [expr {$h + 15}] -t $key1 $w $h $w2 [expr {$h + 15}]
- eval lappend box [dialog::buttonSet 10 $h]
- incr h 17
- } else {
- lappend box -t [lindex $it2 0] 65 $h 205 [expr {$h + 15}] -t $key1 $w $h $w2 [expr {$h + 15}]
- eval lappend box [dialog::buttonSet 10 [expr {$h +8}]]
- incr h 17
- if {$key1 != "<no binding>"} {regsub {((ctrl-)?(shift-)?)(.*)} $key1 {\1opt-\4} key1}
- lappend box -t [lindex $it2 1] 65 $h 205 [expr {$h + 15}] -t $key1 $w $h $w2 [expr {$h + 15}]
- incr h 17
- }
- if {$it != [lindex $items [expr {[llength $items] -1}]] && !$twoWindows && [set twoWindows [expr {$h + 100 > $screenHeight}]]} {
- set box " -n [list [concat Page 1 of $name]] $box -n [list [concat Page 2 of $name]] "
- set hmax $h; set h 30
- }
- }
- if {[info exists hmax]} {set h $hmax}
- if {$twoWindows} {
- set top "-m [list [list $page [concat Page 1 of $name] [concat Page 2 of $name]]] 10 10 370 25"
- } else {
- set top "-t [list $name] 50 10 250 25"
- }
- set buttons "-b OK 20 [expr {$h + 10}] 85 [expr {$h + 30}] -b Cancel 105 [expr {$h + 10}] 170 [expr {$h + 30}]"
- set values [eval [concat dialog -w 380 -h [expr {$h + 40}] $buttons $top $box]]
- if {$twoWindows} {set page [lindex $values 2]}
- if {[lindex $values 1]} {
- # Cancel
- return "Cancel"
- } elseif {[lindex $values 0]} {
- # Save new key bindings
- foreach it $modified {
- set key_changes($it) $tmpKeys($it)
- }
- return
- } else {
- # Get a new key.
- set it [lindex [lindex $items [expr {[lsearch $values 1] - 2 - $twoWindows}]] 1]
- if {![catch {dialog::getAKey $it $tmpKeys($it) $for_menu} newKey] && $newKey != $tmpKeys($it)} {
- set tmpKeys($it) $newKey
- lappend modified $it
- }
- }
- }
- }
-
-
-